package com.hefan.live.listener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;

import com.hefan.common.ons.TopicRegistryDev;
import com.hefan.common.ons.TopicRegistryTest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.cat.common.entity.ResultBean;
import com.cat.common.meta.ResultCode;
import com.cat.tiger.service.JedisService;
import com.cat.tiger.util.GlobalConstants;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hefan.common.ons.TopicRegistry;
import com.hefan.common.ons.listener.GLLMessageListener;
import com.hefan.common.util.DynamicProperties;
import com.hefan.common.util.MapUtils;
import com.hefan.live.bean.LiveRoomPersonVo;
import com.hefan.live.itf.LiveImOptService;
import com.hefan.live.itf.LivingRedisOptService;
import com.hefan.live.itf.RoomEnterExitOptService;

/**
 * 用户进出直播间队列消息处理
 * 
 * @author kevin_zhang
 *
 */
@Component
public class LiveLogPersonOptListener implements GLLMessageListener {
	Logger logger = LoggerFactory.getLogger(LiveLogPersonOptListener.class);

	int MAX_PAGE_SIZE = 20;
	int MIN_SPECIAL_EFFECTS_LEVEL = 21;

	@Resource
	JedisService jedisService;
	@Resource
	LiveImOptService liveImOptService;
	@Resource
	RoomEnterExitOptService roomEnterExitOptService;
	@Resource
	LivingRedisOptService livingRedisOptService;

	@Override
	public TopicRegistry getTopicRegistry() {
		return TopicRegistry.HEFAN_LIVE_ENTER;
	}

	@Override
	public TopicRegistryDev getTopicRegistryDev() {
		return TopicRegistryDev.HEFAN_LIVE_ENTER_DEV;
	}

	@Override
	public TopicRegistryTest getTopicRegistryTest() {
		return TopicRegistryTest.HEFAN_LIVE_ENTER_TEST;
	}

	@SuppressWarnings({ "rawtypes" })
	@Override
	public Action consume(Message arg0, ConsumeContext arg1) {
		String realTopic = arg0.getTag();
		logger.info("HEFAN_LIVE_ENTER receiver MessageListener topic: {}, realTopic : {}, msg_body: {}",
				arg0.getTopic(), realTopic, new String(arg0.getBody()));
		try {
			Map paramMap = new ObjectMapper().readValue(arg0.getBody(), Map.class);
			if (null != paramMap && !paramMap.isEmpty()) {
				if (paramMap.containsKey("joinLiveRoomVo")) {
					/**
					 * 用户进入直播间
					 */
					logger.info("用户进出直播间－－joinLiveRoomVo");
					String paramStr = (String) paramMap.get("joinLiveRoomVo");
					if (StringUtils.isBlank(paramStr)) {
						logger.info("用户进出直播间－－参数不正确：" + paramStr);
						return Action.CommitMessage;
					}
					Map joinLiveRoomMap = JSON.parseObject(paramStr, Map.class);
					if (null == joinLiveRoomMap || joinLiveRoomMap.isEmpty()) {
						logger.info("用户进出直播间－－参数不完整");
						return Action.CommitMessage;
					}
					return dealJoinLiveRoom(joinLiveRoomMap);
				} else if (paramMap.containsKey("leftLiveRoomVo")) {
					/**
					 * 用户离开直播间
					 */
					logger.info("用户进出直播间－－leftLiveRoomVo");
					String paramStr = (String) paramMap.get("leftLiveRoomVo");
					if (StringUtils.isBlank(paramStr)) {
						logger.info("用户进出直播间－－参数不正确：" + paramStr);
						return Action.CommitMessage;
					}
					Map leftLiveRoomVo = JSON.parseObject(paramStr, Map.class);
					if (null == leftLiveRoomVo || leftLiveRoomVo.isEmpty()) {
						logger.info("用户进出直播间－－参数不完整");
						return Action.CommitMessage;
					}
					return dealLeftLiveRoom(leftLiveRoomVo);
				} else {
					logger.info("用户进出直播间－－无任何操作");
				}
			} else {
				logger.info("用户进出直播间－－无参数");
			}
			return Action.CommitMessage;
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("用户进出直播间－－直播间用户操作失败：" + e.getMessage());
			return Action.ReconsumeLater;
		} finally {
			logger.info("HEFAN_LIVE_ENTER receiver finish");
		}
	}

	/**
	 * 处理用户进入直播间
	 * 
	 * @param joinLiveRoomMap
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Action dealJoinLiveRoom(Map joinLiveRoomMap) {
		String userId = MapUtils.getStrValue(joinLiveRoomMap, "userId", "");// 进入直播间用户id
		int chatRoomId = MapUtils.getIntValue(joinLiveRoomMap, "chatRoomId", -1);// 进入直播间对应聊天室id
		/**
		 * 0:用户 1:网红 2:明星 3:片场 4 内部员工;5:经纪人 6:虚拟币用户
		 */
		int userType = MapUtils.getIntValue(joinLiveRoomMap, "userType", -1);// 进入直播间用户类型，
		String nickName = MapUtils.getStrValue(joinLiveRoomMap, "nickName", "");// 进入直播间用户昵称
		String headImg = MapUtils.getStrValue(joinLiveRoomMap, "headImg", "");// 进入直播间用户头像
		int userLevel = MapUtils.getIntValue(joinLiveRoomMap, "userLevel", -1);// 进入直播间用户等级
		String liveUuid = MapUtils.getStrValue(joinLiveRoomMap, "liveUuid", "");// 直播间UUID
		String authoruserId = MapUtils.getStrValue(joinLiveRoomMap, "authoruserId", "");// 主播id

		if (StringUtils.isBlank(userId) || StringUtils.isBlank(nickName) || chatRoomId < 0 || userType < 0
				|| StringUtils.isBlank(headImg) || userLevel < 0 || StringUtils.isBlank(liveUuid)
				|| StringUtils.isBlank(authoruserId)) {
			logger.info("用户进出直播间－－参数校验不通过");
			return Action.CommitMessage;
		}

		logger.info("用户进出直播间－－更新直播间用户列表－Start");
		String infoRedis = livingRedisOptService.getLivingHomePageUserListInfo(liveUuid);
		logger.info("获取其它直播间首页用户列表：" + infoRedis);
		List<Map> oUserList = StringUtils.isNotBlank(infoRedis) ? JSON.parseObject(infoRedis, List.class)
				: new ArrayList<>();
		if (oUserList.size() > 0) {
			for (Map itemMap : oUserList) {
				LiveRoomPersonVo item = JSON.parseObject((JSON.toJSONString(itemMap)), LiveRoomPersonVo.class);
				if (item.getUserId().equals(userId)) {
					logger.info("更新用户列表IM");
					updateUserList(chatRoomId, liveUuid, authoruserId, userId);
					break;
				}
			}
		}
		logger.info("用户进出直播间－－更新直播间用户列表－End");

		logger.info("用户进出直播间－－特效消息发送－－－－－－userType=" + userType + " userLevel=" + userLevel);
		// 特效：1:网红 2:明星 3:片场，（0:普通用户 4 内部员工;5:经纪人 6:虚拟币用户等级 >= 21）
		if (userType == 3 || userType == 2 || userType == 1 || (userLevel >= MIN_SPECIAL_EFFECTS_LEVEL)) {
			logger.info("用户进出直播间－－特效消息发送－－－开始");
			Map userInfo = new HashMap<>();
			userInfo.put("userId", userId);
			userInfo.put("nickName", nickName);
			userInfo.put("userLevel", userLevel);
			userInfo.put("userType", userType);

			try {
				if (livingRedisOptService.IMSendCheck(authoruserId, 5)) {
					ResultBean resultBean = liveImOptService.highLevelUserIm(chatRoomId, liveUuid, authoruserId,
							JSONObject.toJSONString(userInfo));
					if (resultBean.getCode() == ResultCode.SUCCESS.get_code()) {
						logger.info("用户进出直播间－－高等级用户 " + nickName + " 进入直播间" + chatRoomId + "_" + liveUuid
								+ "特效IM消息发送成功！");
					} else {
						logger.info("用户进出直播间－－高等级用户 " + nickName + " 进入直播间" + chatRoomId + "_" + liveUuid
								+ "特效IM消息发送失败！" + resultBean.getCode() + " msg=" + resultBean.getCode());
					}
				} else {
					logger.info("用户进出直播间－－不满足特效发送策略要求");
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.info("用户进出直播间－－直播间特效消息处理出错");
			}
			logger.info("用户进出直播间－－特效消息发送－－－结束");
		}
		return Action.CommitMessage;
	}

	/**
	 * 处理用户离开直播间
	 * 
	 * @param leftLiveRoomVo
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private Action dealLeftLiveRoom(Map leftLiveRoomVo) {
		String liveUuid = MapUtils.getStrValue(leftLiveRoomVo, "liveUuid", "");// 直播间UUID
		int chatRoomId = MapUtils.getIntValue(leftLiveRoomVo, "chatRoomId", -1);// 进入直播间对应聊天室id
		String authoruserId = MapUtils.getStrValue(leftLiveRoomVo, "authoruserId", "");// 主播id
		String userId = MapUtils.getStrValue(leftLiveRoomVo, "userId", "");// 进入直播间用户id

		if (StringUtils.isBlank(userId) || chatRoomId < 0 || StringUtils.isBlank(liveUuid)
				|| StringUtils.isBlank(authoruserId)) {
			logger.info("用户进出直播间－－参数校验不通过");
			return Action.CommitMessage;
		}

		// 更新用户列表IM
		updateUserList(chatRoomId, liveUuid, authoruserId, userId);
		return Action.CommitMessage;
	}

	/**
	 * 更新用户列表IM
	 * 
	 * @param chatRoomId
	 * @param liveUuid
	 * @param authoruserId
	 * @param userId
	 */
	private void updateUserList(int chatRoomId, String liveUuid, String authoruserId, String userId) {
		logger.info("用户进出直播间－－直播间更新用户列表开始");
		try {
			long limitNum = DynamicProperties.getLong("im_user_list_person_num_limit");
			int mixTime = DynamicProperties.getInt("im_user_list_mix_time");
			long liveRoomNum = roomEnterExitOptService.getLiveRoomPeoleCount(authoruserId);

			if (limitNum > 0 && liveRoomNum <= limitNum) {
				logger.info("用户进出直播间－－用户数小于等于最小设置人数：" + limitNum);
				roomEnterExitOptService.sendUpdateUserListIM(chatRoomId, liveUuid, authoruserId);
			} else {
				/**
				 * 用户列表发送规则： 直播间人数超出 im_user_list_person_num_limit 阀值时，
				 * im_user_list_mix_time 时间内发送一跳更新用户列表的IM消息
				 */
				logger.info("用户进出直播间－－用户数大于最小设置人数：" + limitNum);
				if (StringUtils.isBlank(jedisService.getStr(GlobalConstants.IM_USER_LIST_KEY + chatRoomId))) {
					logger.info("用户进出直播间－－写入IM用户列表消息发送");
					jedisService.incr(GlobalConstants.IM_USER_LIST_KEY + chatRoomId);
					jedisService.expire(GlobalConstants.IM_USER_LIST_KEY + chatRoomId, mixTime);

					roomEnterExitOptService.sendUpdateUserListIM(chatRoomId, liveUuid, authoruserId);
				} else {
					if (jedisService.incr(GlobalConstants.IM_USER_LIST_KEY + chatRoomId) >= 1) {
						logger.info("用户进出直播间－－超出可发消息数");
					} else {
						logger.info("用户进出直播间－－发生意外");
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("用户进出直播间－－直播间更新用户列表消息处理出错");
		}
		logger.info("用户进出直播间－－直播间更新用户列表结束");
	}
}